package com.cb.controller;

import com.cb.dto.CurrentUser;
import com.cb.dto.LoginUser;
import com.cb.entity.Auth;
import com.cb.entity.User;
import com.cb.service.AuthService;
import com.cb.service.UserService;
import com.cb.utils.DigestUtil;
import com.cb.utils.Result;
import com.cb.utils.TokenUtils;
import com.cb.utils.WarehouseConstants;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
public class LoginController {

    //注入id引用名为captchaProducer的Producer接口的实现类DefaultKaptcha的bean对象
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private AuthService authService;

    /**
     * 生成验证码图片
     */
    @GetMapping("/captcha/captchaImage")
    public void getKaptchaImage(HttpServletResponse response){
        ServletOutputStream out=null;
        try {
            //生成验证码文本
            String code = captchaProducer.createText();
            //生成验证码图片
            BufferedImage image = captchaProducer.createImage(code);
            //将验证码文本存储到redis（过期时间60秒）
            stringRedisTemplate.opsForValue().set(code,code,60, TimeUnit.SECONDS);
            //响应正文为jpg图片即验证码图片
            response.setContentType("image/jpeg");
            //将验证码图片响应给浏览器
            out = response.getOutputStream();
            ImageIO.write(image,"jpg",out);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginUser loginUser){
        //验证码校验
        String code = loginUser.getVerificationCode();
        if(!stringRedisTemplate.hasKey(code)){
            return Result.err(Result.CODE_ERR_BUSINESS, "验证码不正确！");
        }
        //根据用户名查询用户
        User user = userService.findUserByCode(loginUser.getUserCode());
        if(user==null){ //没有查到用户
            return Result.err(Result.CODE_ERR_BUSINESS,"该用户不存在！");
        }
        //查到的用户状态是未审核
        if (!user.getUserState().equals(WarehouseConstants.USER_STATE_PASS)) {
            return Result.err(Result.CODE_ERR_BUSINESS,"用户未审核！");
        }
        //将用户录入的密码进行加密
        String password = DigestUtil.hmacSign(loginUser.getUserPwd());
        //查到的用户的密码和用户录入的密码不同
        if (!password.equals(user.getUserPwd())) {
            return Result.err(Result.CODE_ERR_BUSINESS, "密码不正确！");
        }
        //查到的用户的密码和用户录入的密码相同
        //生成token并响应给前端
        CurrentUser currentUser = new CurrentUser(user.getUserId(), user.getUserCode(), user.getUserName());
        String token = tokenUtils.loginSign(currentUser, user.getUserPwd());
        return Result.ok("登录成功！",token);
    }

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/curr-user")
    public Result currUser(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //从前端归还的token中解析出当前登录用户的信息
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        return Result.ok(currentUser);
    }

    /**
     * 加载当前登录用户权限(菜单)树
     */
    @GetMapping("/user/auth-list")
    public Result authList(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //从前端归还的token中解析出当前登录用户的信息
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        List<Auth> authTree = authService.findAuthTree(currentUser.getUserId());
        return Result.ok(authTree);
    }

    /**
     * 退出登录
     */
    @DeleteMapping("/logout")
    public Result logout(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //从redis移除token
        stringRedisTemplate.delete(token);
        return Result.ok("退出登录成功！");
    }
}
